package com.difed.cccam.api.parseadores;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.difed.cccam.entidades.Caid;
import com.difed.cccam.entidades.Servidor;

public final class ParseadorServidores {
    
    private static final String INICIO_CABECERA_1 = "| Host";
    private static final String INICIO_CABECERA_2 = "+-----";
    private static final String PATRON_CAID = "(local|remote) (\\d+:\\d+) (\\d+)\\((\\d+)\\)\\s*";
    
    private ParseadorServidores() {
        
    }
    
    public static List<Servidor> parsea(String result) {
        List<Servidor> servidores = new ArrayList<Servidor>();        
        BufferedReader reader = new BufferedReader(new StringReader(result));
        int estado = 0;
        String[] valores;
        Servidor servidor = null;
        try {
            String linea = reader.readLine();
            while (linea != null) {
                switch (estado) {
                case 0:
                    if (linea.startsWith(INICIO_CABECERA_1)) {
                        estado++;
                    }
                    break;
                case 1:
                    if (linea.startsWith(INICIO_CABECERA_2)) {
                        estado++;
                    }
                    break;
                case 2:
                    if (linea.startsWith("|")) {
                        valores = linea.substring(1).split("\\|");
                        if (valores[0].trim().length() > 0) {
                            servidor = creaServidor(valores);
                            servidores.add(servidor);
                        } else {
                            leeEcm(servidor, valores[6]);
                        }
                    } else {
                        estado++;
                    }
                    break;
                }
                if (estado < 3) {
                    linea = reader.readLine();
                } else {
                    break;
                }                
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return servidores;
    }
    
    public static void completaServidores(String result, List<Servidor> servidores, 
    		Map<String, Map<String, String>> mapCaids) {
        Map<String, Servidor> mapaServidores = new HashMap<String, Servidor>();
        for (Servidor servidor : servidores) {
            mapaServidores.put(servidor.getHost(), servidor);
        }
        BufferedReader reader = new BufferedReader(new StringReader(result));
        int estado = 0;
        String[] valores;
        try {
            String linea = reader.readLine();
            while (linea != null) {
                switch (estado) {
                case 0:
                    if (linea.startsWith(INICIO_CABECERA_1)) {
                        estado++;
                    }
                    break;
                case 1:
                    if (linea.startsWith(INICIO_CABECERA_2)) {
                        estado++;
                    }
                    break;
                case 2:
                    if (linea.startsWith("|")) {
                        valores = linea.substring(1).split("\\|");
                        completaServidor(mapaServidores, valores, mapCaids);
                    } else {
                        estado++;
                    }
                    break;
                }
                if (estado < 3) {
                    linea = reader.readLine();
                } else {
                    break;
                }                
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private static void completaServidor(Map<String, Servidor> mapaServidores, String[] valores,
    		Map<String, Map<String, String>> mapCaids) {
        Servidor servidor = mapaServidores.get(valores[0].trim());
        if (servidor != null) {
            if (valores[5].startsWith("1")) {
                servidor.setLocales(servidor.getLocales() + 1);
                int reshared = Integer.parseInt(valores[5].substring(1).trim());
                if (servidor.getReshared() < reshared) {
                	servidor.setReshared(reshared);
                }
                String[] caids = valores[4].trim().split(",");
                if (caids[0].length() > 0) {
                    boolean repetido = false;
                    
                    String caidId = valores[2].trim();
                    String sistema = valores[3].trim();
                    
                    Caid tmpCaid;
                    for (int i = 0; i < caids.length; i++) {
                        if (servidor.getCaids() == null) {
                            servidor.setCaids(new ArrayList<Caid>());
                        }
                        for (Caid caid : servidor.getCaids()) {
                            if (caid.getCodigo() == caids[i]) {
                                repetido = true;
                                break;
                            }
                        }
                        if (!repetido) {
                            tmpCaid = new Caid();
                            tmpCaid.setCodigo(caids[i].toUpperCase());
                            tmpCaid.setCaid(caidId.toUpperCase());
                            tmpCaid.setSistema(sistema);
                            if (mapCaids.containsKey(tmpCaid.getCaid())){
                            	tmpCaid.setDefinicion(mapCaids.get(tmpCaid.getCaid()).get(tmpCaid.getCodigo()));
    	            		}
                            servidor.getCaids().add(tmpCaid);
                        }
                    }
                }
            } else if (valores[5].startsWith("2")) {
                servidor.setHop2(servidor.getHop2() + 1);
            } else if (valores[5].startsWith("3")) {
                servidor.setHop3(servidor.getHop3() + 1);
            } else if (valores[5].startsWith("0")) {
                servidor.setReshared(Integer.parseInt(valores[5].substring(1).trim()));
            }
        }
    }

    private static Servidor creaServidor(String[] valores) {
        Servidor servidor = new Servidor();
        servidor.setHost(valores[0].trim());
        servidor.setConectado(valores[1].trim().length() > 0);
        servidor.setTipoConexion(valores[2].trim());
        servidor.setVersion(valores[3].trim());
        servidor.setNodeId(valores[4].trim());
        servidor.setShares(Integer.parseInt(valores[5].trim()));
        leeEcm(servidor, valores[6]);
        return servidor;
    }
    
    private static void leeEcm(Servidor servidor, String caidString) {
        Pattern pattern = Pattern.compile(PATRON_CAID);
        Matcher matcher = pattern.matcher(caidString);
        if (matcher.matches()) {        
            servidor.setEcmBad(servidor.getEcmBad() + Integer.parseInt(matcher.group(3)));
            servidor.setEcmOk(servidor.getEcmOk() + Integer.parseInt(matcher.group(4)));
        }
    }

}
